#	Plugin interface
#		methods: search, search_by_ref, init, title, version, desc
#
#
#
#	Grabber plugin
#		TTVDB
#		Uses the ttvdb.py script that comes with Mythtv 0.22
#		Requires python 2.5 and elementtree module

package grabbers::ttvdb;

use HTML::Parser;
use HTML::TreeBuilder;
use HTML::Entities;
use LWP::Simple;
use LWP::UserAgent;
use Getopt::Long;
use Text::Levenshtein qw(distance);


# Exports
our $VERSION = "2.1";
sub title
{
	return "Ttvdb";
}
sub desc
{
	return "Search on The TV database using Mythtv ttvdb.py";
}
sub version
{
	my $ver_string;
	$ttvdb_pid = open(RESULT, "$ttvdb_script -v |");
	unless ($ttvdb_pid)
	{
		die "Can't run $ttvdb_script";
	}
	while ( $line = <RESULT>)
	{
		if($line =~ /<version>(.+?)<\/version>/)
		{
			$ver_string = $1;
			last;
		}
	}
	close(RESULT);
	return $VERSION.", ttvdb.py: ".$ver_string;
}
#end Exports

our $ttvdb_script = "";
our $broken = 0;

sub search 
{
	my $self = shift;
	my $title = shift;
	my $subtitle = shift;
	my $season = shift;
	my $episode = shift;
	my $year = shift;
	my %details;
	if ( $broken == 0 )
	{
		if( (length $season == 0 || $season == 0) && (length $episode == 0 || $episode == 0) )
		{
			print " Not a TV show\n";
		}
		else
		{
			if( length $season == 0)
			{
				# if no season info, then assume it is season 1
				$season = 1;
			}
			$result = getTtvdbData(\%details, $title, $subtitle, $season, $episode, $year);
		}
	}
	else
	{
		print " Disabled\n"
	}
	return %details;
}

sub search_by_ref
{
	my $self = shift;
	my $ref = shift;
	my $details;	
	init();
	if(length $ref > 0)
	{
		getImdbData(\$details, $ref);
		getImdbEpisodeData(\$details, $ref);
	}
	return $details;
}

sub init
{
	my $nReturn = 1;
	#look for script
	if( -x "/usr/share/mythtv/metadata/Television/ttvdb.py")
	{
		$ttvdb_script = "/usr/share/mythtv/metadata/Television/ttvdb.py";
	}
	else
	{
		print "ttvdb.pm: Can't find script \"ttvdb.py\"\n";
		$nReturn = 0;
	}
	return $nReturn;
}

sub new
{
    my($class, %args) = @_;
    my $self = bless({}, $class);
    
    if(init())
	{
		return $self;
	}
    else
	{
	    return 0;
	}
}
#######################################
##   UTILITIES
#######################################
sub getTtvdbData
{
	my $file_details = shift;
	my $title = shift;
	my $subtitle = shift;
	my $season = shift;
	my $episode = shift;
	my $year = shift;
	my $gotimages = 0;

	$ttvdb_pid = open(RESULT, "$ttvdb_script -M \"$title\" $season $episode 2>&1 |");
	unless ($ttvdb_pid)
	{
		die "Can't run $ttvdb_script";
	}
	#we may get multiple hits, find best match
	my $line;
	my $line_ref = "";
	my $line_title = "";
	my $best_score = 1000;
	my $best_title = "";
	my $errors;
	while ( $line = <RESULT>)
	{
#		print $line;

		if($line =~ /Unable to contact themoviedb\.org/)
		{
		
			$broken = 1;
			print " Site appears to be down, disabling grabber\n";
		}

		if($line =~ /<item>/)
		{
			$line_ref = "";
			$line_title = "";
		}
		elsif($line =~ /<title>(.+)<\/title>/)
		{
			$line_title = $1;
			$line_title =~ s/\s*\(\d\d\d\d\)$//;
		}
		elsif($line =~ /<inetref>(.+)<\/inetref>/)
		{
			$line_ref = $1;
		}
		elsif($line =~ /<releasedate>(.{4}).*/)
		{
			$line_year = $1;
		}
		if($line_year < 1900)
		{
			undef $line_year;
		}
		if($line =~ /<\/item>/)
		{
			$errors = scoreMatch($title, $line_title);
			if($errors < $best_score)
			{
				$best_score = $errors;
				$best_ref = $line_ref;
				print "  Found Better Match: $line_ref:$line_title\r\n";
			}
			elsif($errors == $best_score)
			{
				if($year == $line_year)
				{
					$best_score = $errors;
					$best_ref = $line_ref;
					print "  Found Better Match: $line_ref:$line_title ($line_year)\r\n";
				}
			}
		}
	}
	close(RESULT);
	if( $broken )
	{
		return;
	}
	$ttvdb_pid = open(RESULT, "$ttvdb_script -D \"$best_ref\" $season $episode 2>&1 |");
	unless ($ttvdb_pid)
	{
		die "Can't run $ttvdb_script";
	}
	while ( $line = <RESULT>)
	{
		if($line =~ /<title>(.+)<\/title>/)
		{
			$file_details->{Title} = $1;
			$file_details->{Title} =~ s/\s*\(\d\d\d\d\)$//;
		}
		elsif($line =~ /<subtitle>(.+)<\/subtitle>/)
		{
			$file_details->{Subtitle} = $1;
		}
		elsif($line =~ /<season>(.+)<\/season>/)
		{
			$file_details->{Season} = $1;
		}
		elsif($line =~ /<episode>(.+)<\/episode>/)
		{
			$file_details->{Episode} = $1;
		}
		elsif($line =~ /<person .*job=\"Director\".*/)
		{
			if(!defined $file_details->{Director})
			{
				$file_details->{Director}=getAttrib($line,"name");
			}
			else
			{
				$file_details->{Director} = $file_details->{Director}.",".getAttrib($line,"name");
			}
		}
		elsif($line =~ /<description>(.+)<\/description>/)
		{
			$file_details->{Plot} = $1;
		}
		elsif($line =~ /<year>(.+)<\/year>/)
		{
			$file_details->{Year} = $1;
		}
		elsif($line =~ /<person .*job=\"(Actor|Guest Star)\".*/)
		{
			if(!defined $file_details->{Cast})
			{
				$file_details->{Cast}=getAttrib($line,"name");
			}
			else
			{
				$file_details->{Cast} = $file_details->{Cast}.",".getAttrib($line,"name");
			}
		}
		elsif($line =~ /<runtime>(.+)<\/runtime>/)
		{
			$file_details->{Length} = $1;
		}
		elsif($line =~ /<image .*type=\"screenshot\".*/)
		{
			if(length $file_details->{ScreenshotUrl} == 0)
			{
				$file_details->{ScreenshotUrl} = getAttrib($line, "url") ;
			}
		}
		elsif($line =~ /<image .*type=\"fanart\".*/)
		{
			if(length $file_details->{FanartUrl} == 0)
			{
				$file_details->{FanartUrl} = getAttrib($line, "url") ;
			}
		}
		elsif($line =~ /<image .*type=\"coverart\".*/)
		{
			if(length $file_details->{PosterUrl} == 0)
			{
				$file_details->{PosterUrl} = getAttrib($line, "url") ;
			}
		}
		elsif($line =~ /<image .*type=\"banner\".*/)
		{
			if(length $file_details->{BannerUrl} == 0)
			{
				$file_details->{BannerUrl} = getAttrib($line, "url") ;
			}
		}
		elsif($line =~ /<certification (.+)>/)
		{
			my $cert;
			if(getAttrib($line, "locale") == "us")
			{
				$file_details->{Rating}=getAttrib($line, "name")
			}
			else
			{
				print "Ignoring certification: ".getAttrib($line, "locale").":".getAttrib($line, "name")."\n";
			}
		}
		elsif($line =~ /Unable to contact themoviedb\.org/)
		{
		
			$broken = 1;
			print " Site appears to be down, disabling grabber\n";
		}
	}
	close(RESULT);

}
sub scoreMatch
{
	my $first = shift;
	my $second = shift;
	$first =~ s/[^\w\s]//g;
	$second =~ s/[^\w\s]//g;
	my $errors = distance(lc($first), lc($second));
#	print " Errors between \"$first\" and \"$second\": $errors\r\n";
	return $errors;
}

sub getAttrib
{
	my $tag=shift;
	my $attrib=shift;
	my $data = '';
	($data) = $tag =~ m/$attrib=\"(.*?)\"/;
	return $data;
}


1;
